package com.genghis.ptas.scorm.service.impl;

import com.genghis.core.page.entity.Page;
import com.genghis.core.page.entity.PageParameter;
import com.genghis.core.page.entity.Page;
import com.genghis.core.page.entity.PageParameter;
import com.genghis.ptas.constant.DictConstant;
import com.genghis.ptas.scorm.dao.ScormDao;
import com.genghis.ptas.scorm.entity.NodesInfo;
import com.genghis.ptas.scorm.entity.SCOInfo;
import com.genghis.ptas.scorm.entity.ScormInfo;
import com.genghis.ptas.scorm.entity.UserCourseInfo;
import com.genghis.ptas.scorm.service.UpScormService;
import com.genghis.ptas.security.dao.UserDao;
import com.genghis.ptas.security.service.UserService;
import com.genghis.ptas.system.service.DictService;
import com.genghis.ptas.util.LoginUserUtil;
import com.genghis.ptas.util.UploadZipAndUNZip;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.xml.sax.SAXException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: tiangc
 * Date: 14-4-22
 * Time: 下午8:16
 * To change this template use File | Settings | File Templates.
 */
@Transactional
@Service("upScormService")
public class UpScormServiceImpl implements UpScormService {
    @Autowired
    private ScormDao scormDao;

    @Autowired
    private DictService dictService;

    @Autowired
    private UserDao userDao;

    @Override
    //返回解压后的清单文件的url
    public String upScorm(HttpServletRequest request, CommonsMultipartFile upFile) throws ServletException, IOException {
        //统一上传到webApp的 UP_SCORM_ZIP包下
        String upPath = "\\" + DictConstant.UP_SCORM_ZIP;

        //如果该路径不存在则创建
        File file = new File(upPath);
        if (!file.exists()) {
            file.mkdirs();
        }
        UploadZipAndUNZip uploadZipAndUNZip = new UploadZipAndUNZip();
        String fileNamePath = uploadZipAndUNZip.uploadFile(request, upFile, upPath);

        //解压ZIP
        uploadZipAndUNZip.unZip(fileNamePath);

        //获得解压后的imsmanifest.xml的url
        String xmlUrl = fileNamePath.replaceAll(upFile.getOriginalFilename(), DictConstant.IMSMANIFEST);

        return xmlUrl;

    }

    //解析清单文件，返回章节信息List
    public List<NodesInfo> analyzeIms(String imsUrl) throws IOException {
        UploadZipAndUNZip uploadZipAndUNZip = new UploadZipAndUNZip();
        try {
            //返回解压后的多个xmlInfo的信息
            return uploadZipAndUNZip.analyzeXml(imsUrl);
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (XPathExpressionException e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    public void addScorm(List<NodesInfo> nodesInfoList, String zipInfo, int userId, String imsUrl) {
        ScormInfo scormInfo = new ScormInfo();
        String info[] = zipInfo.split(",");
        String scormName = null;
        String scormDisc = null;
        try {
            scormName = URLDecoder.decode(info[0], "utf-8");
            scormDisc = URLDecoder.decode(info[2], "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        scormInfo.setScormName(scormName);
        scormInfo.setCourseType(Integer.parseInt(info[1]));
        scormInfo.setCourseDisc(scormDisc);
        scormInfo.setUploadTime(info[3]);
        scormInfo.setUploadUserId(userId);
        scormInfo.setRegistNum(0);
        scormInfo.setImsUrl(imsUrl);

        int scormId = scormDao.addScorm(scormInfo);
        for (NodesInfo nodesInfo : nodesInfoList) {
            nodesInfo.setScormId(scormId);
            if (nodesInfo.getShowNodeType().equals(DictConstant.TYPE_ORGANIZATION)) {
                nodesInfo.setNodeType(0);
            } else {
                nodesInfo.setNodeType(1);
            }
            scormDao.addNodesInfo(nodesInfo);
        }
    }

    @Override
    public void delCourse(String[] courseIds) {
        for (String courseId : courseIds) {
            scormDao.delCourse(Integer.parseInt(courseId));

        }
    }

    @Override
    public void registScorm(int id, int userId) {
        ScormInfo scormInfo = scormDao.findScormInfoById(id);
        scormInfo.setRegistNum(scormInfo.getRegistNum() + 1);

        UserCourseInfo userCourseInfo = new UserCourseInfo();
        userCourseInfo.setUserId(userId);
        userCourseInfo.setScormId(id);

        scormDao.registScorm(scormInfo);
        scormDao.addUserCourseInfo(userCourseInfo);
    }

    @Override
    public List<NodesInfo> listAllCourseByScormId2(int scormId) {
        return scormDao.listAllCourseByScormId(scormId);
    }

    @Override
    public List<NodesInfo> listAllCourseByScormId(int scormId) throws IOException {
        String imsUrl = scormDao.findScormInfoById(scormId).getImsUrl();
        UploadZipAndUNZip uploadZipAndUNZip = new UploadZipAndUNZip();
        try {
            //返回解压后的多个NodesInfo的信息
            List<NodesInfo> nodesInfoList = uploadZipAndUNZip.analyzeXml(imsUrl);
            return nodesInfoList;
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (XPathExpressionException e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    public boolean isRegistScorm(int id, int userId) {
        UserCourseInfo userCourseInfo = new UserCourseInfo();
        userCourseInfo.setScormId(id);
        userCourseInfo.setUserId(userId);
        return scormDao.isRegistScorm(userCourseInfo);
    }

    @Override
    public Page findUpFilePageList(PageParameter pageParameter, ScormInfo scormInfo, int userId) {
        Page<ScormInfo> scormInfoPage = scormDao.findScormInfoPage(pageParameter, scormInfo, userId);
        for (ScormInfo scormInfoPage1 : scormInfoPage.getResultList()) {
            scormInfoPage1.setShowCourseType(dictService.changeDictCodeToValue(scormInfoPage1.getCourseType(), DictConstant.COURSE_TYPE));
        }
        return scormInfoPage;

    }

    @Override
    public Page findCoursingPageListByUserId(PageParameter pageParameter, ScormInfo scormInfo, int userId) {
        Page<ScormInfo> scormInfoPage = scormDao.findCoursePageListByUserId(pageParameter, scormInfo, userId);
        Page<ScormInfo> learningScorm=new Page<ScormInfo>();
        List<ScormInfo> scormList = new ArrayList<ScormInfo>();
        for (ScormInfo scormInfoPage1 : scormInfoPage.getResultList()) {
            if(!isLearnedScorm(scormInfoPage1.getId(),userId)){
                scormList.add(scormInfoPage1);
                learningScorm.setResultList(scormList);
               }else if(isLearnedScorm(scormInfoPage1.getId(),userId)&&!isCompletedScorm(scormInfoPage1.getId(),userId)){
                scormList.add(scormInfoPage1);
                learningScorm.setResultList(scormList);
            }
            scormInfoPage1.setShowCourseType(dictService.changeDictCodeToValue(scormInfoPage1.getCourseType(), DictConstant.COURSE_TYPE));
        }
        return learningScorm;
    }

    @Override
    public Page findCoursedPageListByUserId(PageParameter pageParameter, ScormInfo scormInfo, int userId) {
        Page<ScormInfo> scormInfoPage = scormDao.findCoursePageListByUserId(pageParameter, scormInfo, userId);
        Page<ScormInfo> learnedScorm=new Page<ScormInfo>();
        List<ScormInfo> scormList = new ArrayList<ScormInfo>();
        for (ScormInfo scormInfoPage1 : scormInfoPage.getResultList()) {
            if(isLearnedScorm(scormInfoPage1.getId(),userId)&&isCompletedScorm(scormInfoPage1.getId(),userId)){
                scormList.add(scormInfoPage1);
                learnedScorm.setResultList(scormList);
            }
            scormInfoPage1.setShowCourseType(dictService.changeDictCodeToValue(scormInfoPage1.getCourseType(), DictConstant.COURSE_TYPE));
        }
        return learnedScorm;
    }

    @Override
    public ScormInfo findScormInfoById(int id) {
        return scormDao.findScormInfoById(id);
    }

    @Override
    public List<ScormInfo> findScormInfoPageList() {
        List<ScormInfo> scormInfos = scormDao.findScormInfoPageList();
        for (ScormInfo oneScormInfo : scormInfos) {
            String userName = userDao.findUserAllInfoById(oneScormInfo.getUploadUserId()).getLoginName();
            oneScormInfo.setUploadUser(userName);
            oneScormInfo.setShowCourseType(dictService.changeDictCodeToValue(oneScormInfo.getCourseType(), DictConstant.COURSE_TYPE));
        }
        return scormInfos;
    }

    @Override
    public void addSCOInfo(SCOInfo scoInfo) {
        scoInfo.setCoreStudentName(userDao.findUserAllInfoById(scoInfo.getCoreStudentId()).getLoginName());
        scormDao.addSCOInfo(scoInfo);

    }

    @Override
    public SCOInfo getSCOInfoByNodeIdAndStuId(SCOInfo scoInfo) {
        return scormDao.getSCOInfoByNodeIdAndStuId(scoInfo);
    }

    @Override
    public void updateSCOInfoByNodeIdAndStuId(SCOInfo scoInfo) {
        scoInfo.setCoreStudentName(userDao.findUserAllInfoById(scoInfo.getCoreStudentId()).getLoginName());
        scormDao.updateSCOInfoByNodeIdAndStuId(scoInfo);
    }

    @Override
    public boolean isLearnedScorm(int scormId, int userId) {
        List<NodesInfo> nodesInfoList = scormDao.listAllCourseByScormId(scormId);
        boolean flag=false;
        for (NodesInfo nodesInfo : nodesInfoList) {
            SCOInfo scoInfo = new SCOInfo();
            scoInfo.setNodeId(nodesInfo.getId());
            scoInfo.setCoreStudentId(userId);
            SCOInfo scoInfo1 = scormDao.getSCOInfoByNodeIdAndStuId(scoInfo);
            //如果有一个SCOInfo不为空，说明课件学习过则返回true
            if(scoInfo1!=null){
                flag=true;
                break;
            }
        }
        return flag;
    }

    @Override
    public boolean isCompletedScorm(int scormId, int userId) {
        List<NodesInfo> nodesInfoList = scormDao.listAllCourseByScormId(scormId);
        boolean flag=true;
        for (NodesInfo nodesInfo : nodesInfoList) {
            SCOInfo scoInfo = new SCOInfo();
            scoInfo.setNodeId(nodesInfo.getId());
            scoInfo.setCoreStudentId(userId);
            SCOInfo scoInfo1 = scormDao.getSCOInfoByNodeIdAndStuId(scoInfo);
            //只要有一个SCOInfo的为空，就说明这个课件没有完成，返回false否则返回true
            if(scoInfo1==null){
                flag=false;
                break;
            }
        }
        return flag;
    }

    @Override
    public List<ScormInfo> listAllScormByUploadTime() {
        List<ScormInfo> scormInfoList= scormDao.listAllScormByUploadTime();
        for(ScormInfo scormInfo:scormInfoList){
            String userName = userDao.findUserAllInfoById(scormInfo.getUploadUserId()).getLoginName();
            scormInfo.setUploadUser(userName);
            scormInfo.setShowCourseType(dictService.changeDictCodeToValue(scormInfo.getCourseType(), DictConstant.COURSE_TYPE));
        }

        return scormInfoList;
    }

    @Override
    public List<ScormInfo> listAllScormByRegistNum() {
        List<ScormInfo> scormInfoList= scormDao.listAllScormByRegistNum();
        for(ScormInfo scormInfo:scormInfoList){
            String userName = userDao.findUserAllInfoById(scormInfo.getUploadUserId()).getLoginName();
            scormInfo.setUploadUser(userName);
            scormInfo.setShowCourseType(dictService.changeDictCodeToValue(scormInfo.getCourseType(), DictConstant.COURSE_TYPE));
        }
        return scormInfoList;
    }

    @Override
    public List<ScormInfo> listAllScormByAvgScore() {
        List<ScormInfo> scormInfoList= scormDao.listAllScormByAvgScore();
        for(ScormInfo scormInfo:scormInfoList){
            String userName = userDao.findUserAllInfoById(scormInfo.getUploadUserId()).getLoginName();
            scormInfo.setUploadUser(userName);
            scormInfo.setShowCourseType(dictService.changeDictCodeToValue(scormInfo.getCourseType(), DictConstant.COURSE_TYPE));
        }
        return  scormInfoList;
    }

    @Override
    public List<ScormInfo> listAllScormByCourseType(int courseType) {
        return scormDao.listAllScormByCourseType(courseType);
    }
    @Override
    public Page findOnlinePageList(PageParameter pageParameter, ScormInfo scormInfo, int userId) {
        Page<ScormInfo> scormInfoPage = scormDao.findOnlinePageList(pageParameter, scormInfo, userId);
        for (ScormInfo scormInfoPage1 : scormInfoPage.getResultList()) {
            scormInfoPage1.setShowCourseType(dictService.changeDictCodeToValue
                    (scormInfoPage1.getCourseType(), DictConstant.COURSE_TYPE));
        }
        return scormInfoPage;

    }

}
